package com.elite.groovy.util;

import com.alibaba.nacos.common.http.BaseHttpMethod;
import com.jcraft.jsch.*;
import com.jcraft.jsch.ChannelSftp.LsEntry;
import com.nimbusds.jose.JWSAlgorithm;
import com.nimbusds.jose.jwk.source.JWKSource;
import com.nimbusds.jose.jwk.source.RemoteJWKSet;
import com.nimbusds.jose.proc.JWSKeySelector;
import com.nimbusds.jose.proc.JWSVerificationKeySelector;
import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.proc.ConfigurableJWTProcessor;
import com.nimbusds.jwt.proc.DefaultJWTProcessor;
import com.wisdge.ezcell.EzCellFactory;
import com.wisdge.utils.DateUtils;
import com.wisdge.utils.FileUtils;
import com.wisdge.utils.RandomUtils;
import com.wisdge.utils.security.AES;
import com.wisdge.utils.security.AESForNodejs;
import com.wisdge.utils.security.RSAUtils;
import com.wisdge.web.IPUtils;
import com.wisdge.web.springframework.SpringContextUtil;
import gui.ava.html.parser.HtmlParserImpl;
import gui.ava.html.renderer.ImageRenderer;
import gui.ava.html.renderer.ImageRendererImpl;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVPrinter;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.params.ConnRoutePNames;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.conn.ssl.TrustAllStrategy;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
import org.apache.poi.openxml4j.util.ZipSecureFile;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipFile;
import org.apache.tools.zip.ZipOutputStream;
import org.elasticsearch.client.Response;
import org.jsoup.Jsoup;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.jdbc.support.rowset.SqlRowSet;
import org.springframework.util.Base64Utils;
import org.springframework.util.CollectionUtils;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.imageio.ImageIO;
import javax.mail.Transport;
import javax.mail.internet.*;
import javax.net.ssl.*;
import javax.servlet.http.HttpServletRequest;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.*;
import java.nio.charset.StandardCharsets;
import java.security.KeyFactory;
import java.security.MessageDigest;
import java.security.PrivateKey;
import java.security.Signature;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.security.spec.PKCS8EncodedKeySpec;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class Util {
    private static final Logger log = LoggerFactory.getLogger(Util.class);
    private static final String CHINESE_CHARSET = "GBK";
    private static final String CSV_COLUMN_SEPARATOR = ",";
    private static final String CSV_ROW_SEPARATOR = System.lineSeparator();
    public static final int MAX_STR_LEN = 1000;

    /**
     * ES 对内容做索引，创建或者更新
     *
     * @param id      索引id
     * @param content 索引内容
     * @param index   索引类型(optional)
     */
    public static String esClientIndex(String id, Object content, String index) throws Exception {
        ESClientFactory esClientFactory = (ESClientFactory) SpringContextUtil.getBean("esClientFactory");
        String examine = "_doc"; //兼容 version 6、7
        String endpoint = '/' + index + '/' + examine + '/' + id;
        JSONObject entity = new JSONObject();
        if (content.getClass().equals(String.class)) {
            entity = JSONObject.fromObject(content);
        } else {
            entity.put("content", content.toString());
        }
        Response res = esClientFactory.performRequest("PUT", endpoint, entity.toString());
        int statusCode = res.getStatusLine().getStatusCode();
        log.debug("response code: " + statusCode);
        HttpEntity responseEntity = res.getEntity();
        if (responseEntity != null) {
            return EntityUtils.toString(responseEntity);
        }
        return null;
    }

    public static String getERRO(Exception e) {
        String str = "";
        try {
            StringWriter sw = new StringWriter();
            e.printStackTrace(new PrintWriter(sw, true));
            str = sw.toString();
        } catch (Exception e1) {
            str = e.toString();
            log.error("getERRO:{}", e1.toString());
        }
        return str;
    }

    public static String aiaencryptMinisite(String text) {
        String m = "a";
        char[] charArray = text.toCharArray();
        for (int i = 1; i < charArray.length; i++) {//第一位字母不加密
            char key = m.charAt(0);
            charArray[i] = (char) (text.charAt(i) ^ key);
        }
        return new String(charArray);
    }

    public static String stringTrim(String str) {
        if (str != null) {
            str = str.replace("\n", "");
            str = str.replace("\r", "");
            str = str.trim();
        }
        return str;
    }

    public static String filterForObject(Object Obj) {
        String str = "";
        if (Obj == null) {
            str = "";
        } else {
            str = filter(Obj.toString());
        }
        return str;
    }

    public static String filter(String str) {
        if (str == null || "null".equals(str)) {
            str = "";
        }
        return str.trim();
    }

    public static void extractTarFile(String tarFilePath, String destDirectory) {
        try (FileInputStream fileInputStream = new FileInputStream(tarFilePath); TarArchiveInputStream tarInput = new TarArchiveInputStream(fileInputStream)) {
            TarArchiveEntry entry;
            while ((entry = tarInput.getNextTarEntry()) != null) {
                if (entry.isDirectory()) {
                    File directory = new File(destDirectory, entry.getName());
                    directory.mkdirs();
                } else {
                    File outputFile = new File(destDirectory, entry.getName());
                    outputFile.getParentFile().mkdirs();
                    try (OutputStream outputFileStream = new FileOutputStream(outputFile)) {
                        byte[] buffer = new byte[4096];
                        int bytesRead;
                        while ((bytesRead = tarInput.read(buffer)) != -1) {
                            outputFileStream.write(buffer, 0, bytesRead);
                        }
                    }
                }
            }
        } catch (IOException e) {
            log.error("", e);
        }
    }

    public static List unzip(String filePath) throws Exception {
        File srcFile = new File(filePath);
        ZipFile zipFile = null;
        ArrayList<String> pathArray = new ArrayList();
        if (!srcFile.exists()) {
            throw new Exception(filePath + " not exist");
        }
        try {
            zipFile = new ZipFile(srcFile, CHINESE_CHARSET);
            Enumeration<?> entries = zipFile.getEntries();
            while (entries.hasMoreElements()) {
                ZipEntry entry = (ZipEntry) entries.nextElement();
                log.debug("unzip:{}", entry.getName());
                String dirPath = srcFile.getParent() + File.separator + entry.getName();
                boolean directoryFlag = false;
                if (entry.isDirectory()) {
                    File dir = new File(dirPath);
                    dir.mkdirs();
                    directoryFlag = true;
                } else {
                    File targetFile = new File(dirPath);
                    if (!targetFile.getParentFile().exists()) {
                        targetFile.getParentFile().mkdirs();
                    }
                    targetFile.createNewFile();
                    try (InputStream is = zipFile.getInputStream(entry); FileOutputStream fos = new FileOutputStream(targetFile);) {
                        int len;
                        byte[] buf = new byte[1024 * 10];
                        while ((len = is.read(buf)) != -1) {
                            fos.write(buf, 0, len);
                        }
                    } catch (Exception e) {
                        throw e;
                    }
                }
                if (!directoryFlag) {
                    pathArray.add(dirPath);
                }
            }
        } catch (Exception e) {
            throw new RuntimeException("unzip error from ZipUtils", e);
        } finally {
            if (zipFile != null) {
                try {
                    zipFile.close();
                } catch (IOException e) {
                    log.error("关闭异常", e.toString());
                }
            }
        }
        return pathArray;
    }

    public static boolean deleteFile(String sPath) {
        boolean flag = false;
        File file = new File(sPath);
        // 路径为文件且不为空则进行删除
        if (file.isFile() && file.exists()) {
            file.delete();
            flag = true;
        }
        return flag;
    }

    public static boolean renameFile(String path, String newName) {
        boolean flag = false;
        File oldfile = new File(path);
        String oldName = oldfile.getName();
        log.debug("oldName:{}", oldName);
        String newPath = oldfile.getParent() + File.separator + newName;
        log.debug("newPath:{}", newPath);
        File newfile = new File(newPath);
        if (oldfile.exists()) {
            if (newfile.exists()) {
                newfile.delete();
            }
            flag = oldfile.renameTo(newfile);
        }
        return flag;
    }

    public static String zip(List pathList, String zipFileName) throws Exception {
        String returnPath = "";
        if (!CollectionUtils.isEmpty(pathList)) {
            int count, bufferLen = 1024;
            byte data[] = new byte[bufferLen];
            try {
                String zipFilePath = new File((String) pathList.get(0)).getParent() + File.separator + zipFileName;
                log.debug("zipFilePath:{}", zipFilePath);
                File zipFile = new File(zipFilePath);
                if (zipFile.exists()) {
                    zipFile.delete();
                }
                try (OutputStream out = new FileOutputStream(zipFilePath); ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(out));) {
                    zos.setEncoding(CHINESE_CHARSET);
                    for (int i = 0; i < pathList.size(); i++) {
                        String filePath = (String) pathList.get(i);
                        log.debug("filePath:{}", filePath);
                        File file = new File(filePath);
                        String fileName = file.getName();
                        log.debug("fileName:{}", fileName);
                        ZipEntry entry = new ZipEntry(fileName);
                        zos.putNextEntry(entry);
                        try (InputStream in = new FileInputStream(file); BufferedInputStream bis = new BufferedInputStream(in);) {
                            while ((count = bis.read(data, 0, bufferLen)) != -1) {
                                zos.write(data, 0, count);
                            }
                        } catch (Exception e1) {
                            log.error("", e1);
                            throw e1;
                        }

                    }
                    returnPath = zipFilePath;
                } catch (Exception e2) {
                    log.error("", e2);
                    throw e2;
                }

            } catch (Exception e) {
                log.error("", e);
            }
        }
        return returnPath;
    }

    public static String callWebService(String wsurl, String xmlBody, String charset, String soapaction, int timeout) throws Exception {
        String result = "";
        URL url = new URL(wsurl);
        if (wsurl.startsWith("https")) {
            SSLContext sslcontext = SSLContext.getInstance("SSLv3");
            sslcontext.init(null, new TrustManager[]{truseAllManager}, new java.security.SecureRandom());
            HostnameVerifier ignoreHostnameVerifier = new HostnameVerifier() {
                @Override
                public boolean verify(String s, SSLSession sslsession) {
                    return true;
                }
            };
            HttpsURLConnection.setDefaultHostnameVerifier(ignoreHostnameVerifier);
            HttpsURLConnection.setDefaultSSLSocketFactory(sslcontext.getSocketFactory());
        }
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("POST");
        conn.setRequestProperty("SOAPAction", soapaction);
        conn.setRequestProperty("Content-Length", String.valueOf(xmlBody.getBytes(charset).length));
        conn.setRequestProperty(Const.CONTENTTYPE, "text/xml; charset=" + charset);
        conn.setRequestProperty("Accept-Charset", charset);
        conn.setDoOutput(true);
        conn.setDoInput(true);
        conn.setConnectTimeout(timeout);
        conn.setReadTimeout(timeout);
        try {
            try (OutputStream output = conn.getOutputStream()) {
                output.write(xmlBody.getBytes(charset));
            }
            StringBuilder sb = new StringBuilder();
            try (BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8))) {
                String str;
                while ((str = br.readLine()) != null) {
                    if (sb.length() > MAX_STR_LEN) {
                        throw new IOException("input too long");
                    }
                    sb.append(str).append("\n");
                }
            }
            result = sb.toString();
            log.debug("result:{}", result);
        } catch (Exception e) {
            log.error("", e);
            throw e;
        } finally {
            if (conn != null) {
                conn.disconnect();
            }
        }
        return result;
    }

    public static void writeLogIntoDB(HttpServletRequest request, String businessId, String url, String param, String content, int statusCode, String errorMsg, String method) {
        CommonConfiguration commonConfiguration = SpringContextUtil.getBean("commonConfiguration");
        int xhrLog = commonConfiguration.getXhrLog();
        log.debug("保存接口请求日志开关: {}", xhrLog);
        if (!Objects.isNull(request)) {
            if (0 != xhrLog) {
                String operateId = RandomUtils.getGUID();
                String traceId = StringUtils.isNotEmpty(businessId) ? businessId : request.getHeader("traceId");
                String dynId = StringUtils.isEmpty(request.getHeader("dynId")) ? "nonDyn" : request.getHeader("dynId");
                String dynName = StringUtils.isEmpty(request.getHeader("dynName")) ? "nonDynName" : request.getHeader("dynName");
                String remoteIP = IPUtils.getRemoteIP(request);
                String staff = request.getHeader("staff");
                String staffId = "";
                String staffName = "";
                try {
                    if (Objects.isNull(staff)) {
                        staffId = "OUTERId";
                        staffName = "OUTER";
                    } else {
                        String staffStr = AESForNodejs.decrypt(staff, "Ngs_Letmein_0308");
                        com.alibaba.fastjson.JSONObject jsonObject = com.alibaba.fastjson.JSONObject.parseObject(staffStr);
                        staffId = jsonObject.getString("id");
                        staffName = jsonObject.getString("name");
                    }
                } catch (Exception e) {
                    log.error("解密staff异常: {}", e.getMessage(), e);
                }
                if (1 == xhrLog || 3 == xhrLog) {
                    // write log into database
                    try {
                        String subParam = param;
                        if (subParam.length() > 4000) {
                            subParam = subParam.substring(0, 3999);
                        }
                        String jsonResult = content;
                        if (jsonResult.length() > 4000) {
                            jsonResult = jsonResult.substring(0, 3999);
                        }
                        if (errorMsg.length() > 1000) {
                            errorMsg = errorMsg.substring(0, 1000);
                        }
                        Object[] objects = new Object[]{operateId, traceId, dynId, method, url, remoteIP, subParam, jsonResult, statusCode, errorMsg, staffId, staffId};
                        log.debug("保存接口请求日志到数据库, operateId: {}, objects: {}", operateId, objects);
                        EliteBean eliteBean = SpringContextUtil.getBean("ebean");
                        eliteBean.recordHttpLog(objects);
                    } catch (Exception e) {
                        log.error("记录日志异常:{}", e.getMessage(), e);
                    }
                }
                if (2 == xhrLog || 3 == xhrLog) {
                    ESClientFactory esClientFactory = SpringContextUtil.getBean("esClientFactory");
                    try {
                        Response queryIndex = esClientFactory.performRequest("GET", "/xhrlog");
                        if (404 == queryIndex.getStatusLine().getStatusCode()) {
                            log.debug("xhrlog索引不存在, 创建索引");
                            Response createIndex = esClientFactory.performRequest("PUT", "/xhrlog", Const.XHR_LOG_INDEX);
                            int createIndexStatusCode = createIndex.getStatusLine().getStatusCode();
                            if (200 != createIndexStatusCode && 201 != createIndexStatusCode) {
                                throw new Exception("创建xhrlog索引失败");
                            }
                            log.debug("成功创建xhrlog索引");
                        }
                        String nowStr = DateUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss");
                        com.alibaba.fastjson.JSONObject entity = new com.alibaba.fastjson.JSONObject();
                        entity.put("operateId", operateId);
                        entity.put("traceId", traceId);
                        entity.put("dynId", dynId);
                        entity.put("dynName", URLDecoder.decode(dynName, "UTF-8"));
                        entity.put("requestMethod", method);
                        entity.put("operateUrl", url);
                        entity.put("operateIp", remoteIP);
                        entity.put("operParam", param);
                        entity.put("jsonResult", content);
                        entity.put("statusCode", statusCode);
                        entity.put("errorMsg", errorMsg);
                        entity.put("createdby", staffId);
                        entity.put("createdbyname", staffName);
                        entity.put("createddate", nowStr);
                        entity.put("modifiedby", staffId);
                        entity.put("modifieddate", nowStr);
                        log.debug("保存接口请求日志到es, operateId: {}, esClientFactory: {}, entity: {}", operateId, esClientFactory.toString(), entity);
                        Response res = esClientFactory.performRequest("PUT", "/xhrlog/_doc/" + operateId, entity.toString());
                        int esStatusCode = res.getStatusLine().getStatusCode();
                        log.debug("保存接口请求日志到es, operateId: {}, esStatusCode: {}", operateId, esStatusCode);
                    } catch (Exception e) {
                        log.error("执行保存接口请求日志到es异常:{}", e.getMessage(), e);
                    }
                }
            }
        }
    }

    public static String doHttpGet(String url, String charset, int timeout, int enableSSLflag, String sslstr) throws Exception {
        return doHttpGet1(url, charset, timeout, enableSSLflag, sslstr, "", null);
    }

    public static String doHttpGet(String url, String charset, int timeout, int enableSSLflag, String sslstr, String businessId, HttpServletRequest request) throws Exception {
        return doHttpGet1(url, charset, timeout, enableSSLflag, sslstr, businessId, request);
    }

    public static String doHttpGet(String url, String charset, int timeout, int enableSSLflag, String businessId, HttpServletRequest request) throws Exception {
        return doHttpGet1(url, charset, timeout, enableSSLflag, "TLS", businessId, request);
    }

    public static String doHttpGet1(String url, String charset, int timeout, int enableSSLflag, String sslstr) throws Exception {
        HttpGet httpgets = new HttpGet(url);
        httpgets.addHeader("Accept", "text/html, groovy/xhtml+xml, */*");
        httpgets.addHeader("Content-Type", "text/plain; charset=" + charset);
        String content = "";
        DefaultHttpClient httpClient = new DefaultHttpClient();
        httpClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, timeout);
        httpClient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, timeout);
        if (enableSSLflag == 1) {
            enableSSL(httpClient, sslstr);
        }
        HttpResponse httpResponse = httpClient.execute(httpgets);
        HttpEntity httpEntity = httpResponse.getEntity();
        if (httpEntity != null) {
            content = EntityUtils.toString(httpEntity, charset);
        }
        httpClient.clearRequestInterceptors();
        httpClient.clearResponseInterceptors();
        return content;
    }

    public static String doHttpGet1(String url, String charset, int timeout, int enableSSLflag, String sslstr, String businessId, HttpServletRequest request) {
        long startTime = System.currentTimeMillis();
        String content = "";
        String errorMsg = "";
        int statusCode = 0;
        int length = 0;
        long executeTime = 0;
        try {
            RestTemplateService restTemplateService = SpringContextUtil.getBean("restTemplateService");
            HttpHeaders headers = new HttpHeaders();
            headers.add("Accept", "text/html, groovy/xhtml+xml, */*");
            headers.add(Const.CONTENTTYPE, "text/plain; charset=" + charset);
            org.springframework.http.HttpEntity entity = new org.springframework.http.HttpEntity(headers);
            ResponseEntity<String> httpEntity = restTemplateService.exchange(url, HttpMethod.GET, (org.springframework.http.HttpEntity<?>) entity, String.class);
            long endTime = System.currentTimeMillis();
            executeTime = endTime - startTime;
            if (httpEntity != null) {
                content = httpEntity.getBody();
                statusCode = httpEntity.getStatusCodeValue();
            }
        } catch (Exception e) {
            log.error("doHttpGet异常:{}", e.getMessage(), e);
            errorMsg = e.getMessage();
            statusCode = 500;
        }
        writeLogIntoDB(request, businessId, url, "", content, statusCode, errorMsg, "GET");
        //交易耗时，当前处理接口日志来源的ip，当前处理接口日志来源的服务，交易返回结果，错误信息等
        String remoteIp = IPUtils.getRemoteIP(request);
        if (content != null) {
            length = content.length();
        }
        postProcessLog("", url, "GET", businessId, remoteIp, "groovy", content, length, executeTime, statusCode, errorMsg, "", "");
        return content;
    }

    public static String doHttpGetUseHead(String url, String charset, int timeout, int enableSSLflag, Map headMap, String sslstr) throws Exception {
        return doHttpGetUseHead1(url, charset, timeout, enableSSLflag, headMap, sslstr, "", 0, false);
    }

    public static String doHttpGetUseHead(String url, String charset, int timeout, int enableSSLflag, Map headMap) throws Exception {
        return doHttpGetUseHead1(url, charset, timeout, enableSSLflag, headMap, "TLS", "", 0, false);
    }

    public static String doHttpGetUseHead(String url, String charset, int timeout, int enableSSLflag, Map headMap, String sslstr, String proxyIP, int proxyPort, boolean proxyFlag) throws Exception {
        return doHttpGetUseHead1(url, charset, timeout, enableSSLflag, headMap, sslstr, proxyIP, proxyPort, proxyFlag);
    }


    public static String doHttpGetUseHead1(String url, String charset, int timeout, int enableSSLflag, Map headMap, String sslstr, String proxyIP, int proxyPort, boolean proxyFlag) throws Exception {
        HttpGet httpgets = new HttpGet(url);
        if (headMap != null) {
            Iterator entries = headMap.entrySet().iterator();
            while (entries.hasNext()) {
                Map.Entry entry = (Map.Entry) entries.next();
                String key = (String) entry.getKey();
                log.debug("key: {}", key);
                String value = (String) entry.getValue();
                log.debug("value: {}", value);
                httpgets.addHeader(key, value);
            }
        }
        String content = "";
        DefaultHttpClient httpClient = new DefaultHttpClient();
        if (proxyFlag) {
            HttpHost proxy = new HttpHost(proxyIP, proxyPort);
            httpClient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
        }
        httpClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, timeout);
        httpClient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, timeout);
        if (enableSSLflag == 1) {
            enableSSL(httpClient, sslstr);
        }
        HttpResponse httpResponse = httpClient.execute(httpgets);
        HttpEntity httpEntity = httpResponse.getEntity();
        if (httpEntity != null) {
            content = EntityUtils.toString(httpEntity, charset);
        }
        httpClient.clearRequestInterceptors();
        httpClient.clearResponseInterceptors();
        httpClient.close();
        return content;
    }

    public static JSONObject doHttpGetReturnResponse(String url, String charset, int timeout, int enableSSLflag, Map headMap, String sslstr, String proxyIP, int proxyPort, boolean proxyFlag) throws Exception {
        JSONObject obj = new JSONObject();
        HttpGet httpgets = new HttpGet(url);
        if (headMap != null) {
            Iterator entries = headMap.entrySet().iterator();
            while (entries.hasNext()) {
                Map.Entry entry = (Map.Entry) entries.next();
                String key = (String) entry.getKey();
                log.debug("key:{}", key);
                String value = (String) entry.getValue();
                log.debug("value:{}", value);
                httpgets.addHeader(key, value);
            }
        }
        String content = "";
        DefaultHttpClient httpClient = new DefaultHttpClient();
        if (proxyFlag) {
            HttpHost proxy = new HttpHost(proxyIP, proxyPort);
            httpClient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
        }
        httpClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, timeout);
        httpClient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, timeout);
        if (enableSSLflag == 1) {
            enableSSL(httpClient, sslstr);
        }
        HttpResponse httpResponse = httpClient.execute(httpgets);
        Header[] responseHead = httpResponse.getAllHeaders();
        HttpEntity httpEntity = httpResponse.getEntity();
        if (httpEntity != null) {
            content = EntityUtils.toString(httpEntity, charset);
        }
        httpClient.clearRequestInterceptors();
        httpClient.clearResponseInterceptors();
        httpClient.close();
        obj.put("body", content);
        obj.put("head", responseHead);
        return obj;
    }

    public static String doHttpPostUseHead(String url, String body, String charset, int timeout, int enableSSLflag, Map headMap, String sslstr) throws Exception {
        return doHttpPostUseHead1(url, body, charset, timeout, enableSSLflag, headMap, sslstr, "", 0, false);
    }

    public static String doHttpPostUseHead(String url, String body, String charset, int timeout, int enableSSLflag, Map headMap) throws Exception {
        return doHttpPostUseHead1(url, body, charset, timeout, enableSSLflag, headMap, "TLS", "", 0, false);
    }

    public static String doHttpPostUseHead(String url, String body, String charset, int timeout, int enableSSLflag, Map headMap, String sslstr, String proxyIP, int proxyPort, boolean proxyFlag) throws Exception {
        return doHttpPostUseHead1(url, body, charset, timeout, enableSSLflag, headMap, sslstr, proxyIP, proxyPort, proxyFlag);
    }

    public static String doHttpPostUseHead1(String url, String body, String charset, int timeout, int enableSSLflag, Map headMap, String sslstr, String proxyIP, int proxyPort, boolean proxyFlag) throws Exception {
        HttpPost httppost = new HttpPost(url);
        if (headMap != null) {
            Iterator entries = headMap.entrySet().iterator();
            while (entries.hasNext()) {
                Map.Entry entry = (Map.Entry) entries.next();
                String key = (String) entry.getKey();
                log.debug("key:{}", key);
                String value = (String) entry.getValue();
                log.debug("value:{}", value);
                httppost.addHeader(key, value);
            }
        }
        String content = "";
        DefaultHttpClient httpClient = new DefaultHttpClient();
        if (proxyFlag) {
            HttpHost proxy = new HttpHost(proxyIP, proxyPort);
            httpClient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
        }
        httpClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, timeout);
        httpClient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, timeout);
        if (enableSSLflag == 1) {
            enableSSL(httpClient, sslstr);
        }
        StringEntity se = new StringEntity(body, charset);
        httppost.setEntity(se);
        HttpResponse httpResponse = httpClient.execute(httppost);
        HttpEntity httpEntity = httpResponse.getEntity();
        if (httpEntity != null) {
            content = EntityUtils.toString(httpEntity, charset);
        }
        httpClient.clearRequestInterceptors();
        httpClient.clearResponseInterceptors();
        httpClient.close();
        return content;
    }

    public static JSONObject doHttpPostReturnResponse(String url, String body, String charset, int timeout, int enableSSLflag, Map headMap, String sslstr, String proxyIP, int proxyPort, boolean proxyFlag) throws Exception {
        JSONObject obj = new JSONObject();
        HttpPost httppost = new HttpPost(url);
        if (headMap != null) {
            Iterator entries = headMap.entrySet().iterator();
            while (entries.hasNext()) {
                Map.Entry entry = (Map.Entry) entries.next();
                String key = (String) entry.getKey();
                log.debug("key:{}", key);
                String value = (String) entry.getValue();
                log.debug("value:{}", value);
                httppost.addHeader(key, value);
            }
        }
        String content = "";
        DefaultHttpClient httpClient = new DefaultHttpClient();
        if (proxyFlag) {
            HttpHost proxy = new HttpHost(proxyIP, proxyPort);
            httpClient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);
        }
        httpClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, timeout);
        httpClient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, timeout);
        if (enableSSLflag == 1) {
            enableSSL(httpClient, sslstr);
        }
        StringEntity se = new StringEntity(body, charset);
        httppost.setEntity(se);
        HttpResponse httpResponse = httpClient.execute(httppost);
        HttpEntity httpEntity = httpResponse.getEntity();
        Header[] responseHead = httpResponse.getAllHeaders();
        if (httpEntity != null) {
            content = EntityUtils.toString(httpEntity, charset);
        }
        httpClient.clearRequestInterceptors();
        httpClient.clearResponseInterceptors();
        httpClient.close();
        obj.put("body", content);
        obj.put("head", responseHead);
        return obj;
    }

    public static String doHttpPost(String url, String body, String charset, int timeout, int enableSSLflag) throws Exception {
        return doHttpPost1(url, body, charset, timeout, enableSSLflag, "TLS", "", null);
    }

    public static String doHttpPost(String url, String body, String charset, int timeout, int enableSSLflag, String sslstr, String businessId, HttpServletRequest request) throws Exception {
        return doHttpPost1(url, body, charset, timeout, enableSSLflag, sslstr, businessId, request);
    }

    public static String doHttpPost(String url, String body, String charset, int timeout, int enableSSLflag, String businessId, HttpServletRequest request) throws Exception {
        return doHttpPost1(url, body, charset, timeout, enableSSLflag, "TLS", businessId, request);
    }

    public static String doHttpPost1(String url, String body, String charset, int timeout, int enableSSLflag, String sslstr, String businessId, HttpServletRequest request) {
        long startTime = System.currentTimeMillis();
        long executeTime = 0;
        String content = "";
        String errorMsg = "";
        int statusCode = 0;
        int length = 0;
        try {
            RestTemplateService restTemplateService = SpringContextUtil.getBean("restTemplateService");
            HttpHeaders headers = new HttpHeaders();
            headers.add("Accept", "text/html, groovy/xhtml+xml, */*");
            headers.add(Const.CONTENTTYPE, "groovy/x-www-form-urlencoded; charset=" + charset);

            org.springframework.http.HttpEntity entity = new org.springframework.http.HttpEntity(body, headers);
            ResponseEntity<String> httpEntity = restTemplateService.exchange(url, HttpMethod.POST, entity, String.class);
            long endTime = System.currentTimeMillis();
            executeTime = endTime - startTime;
            if (httpEntity != null) {
                content = httpEntity.getBody();
            }
        } catch (Exception e) {
            log.error("doHttpPost异常：{}", e.getMessage(), e);
            errorMsg = e.getMessage();
            statusCode = 500;
        }
        writeLogIntoDB(request, businessId, url, body, content, statusCode, errorMsg, "POST");
        String remoteIp = IPUtils.getRemoteIP(request);
        if (content != null) {
            length = content.length();
        }
        postProcessLog("", url, "POST", businessId, remoteIp, "groovy", content, length, executeTime, statusCode, errorMsg, "", body);
        return content;
    }

    private static void enableSSL(DefaultHttpClient httpclient, String sslstr) throws Exception {
        SSLContext sslcontext = SSLContext.getInstance(sslstr);
        sslcontext.init(null, new TrustManager[]{truseAllManager}, null);
        SSLSocketFactory sf = new SSLSocketFactory(sslcontext);
        sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
        Scheme https = new Scheme("https", sf, 443);
        httpclient.getConnectionManager().getSchemeRegistry().register(https);
    }

    private static TrustManager truseAllManager = new X509TrustManager() {
        @Override
        public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
        }

        @Override
        public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
        }

        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[0];
        }
    };

    public static String getNowString(String type) {
        SimpleDateFormat df = new SimpleDateFormat(type);//设置日期格式
        return df.format(new Date());
    }

    public static Date FormatStrDate(String dateString, String type) {
        Date date = null;
        try {
            if (dateString != null && !"".equals(dateString)) {
                SimpleDateFormat sdf = new SimpleDateFormat(type);
                date = sdf.parse(dateString);
            }
        } catch (Exception e) {
            log.error("", e);
        }
        return date;
    }

    public static String getGuid() {
        return UUID.randomUUID().toString();
    }

    public static JSONObject transObject(JSONObject o1) {
        JSONObject o2 = new JSONObject();
        Iterator it = o1.keys();
        while (it.hasNext()) {
            String key = (String) it.next();
            Object object = o1.get(key);
            if (object.getClass().toString().endsWith("String")) {
                o2.accumulate(key.toLowerCase(), object);
            } else if (object.getClass().toString().endsWith("JSONObject")) {
                o2.accumulate(key.toLowerCase(), transObject((JSONObject) object));
            } else if (object.getClass().toString().endsWith("JSONArray")) {
                o2.accumulate(key.toLowerCase(), transArray(o1.getJSONArray(key)));
            } else {
                o2.accumulate(key.toLowerCase(), object);
            }
        }
        return o2;
    }

    public static JSONArray transArray(JSONArray o1) {
        JSONArray o2 = new JSONArray();
        for (int i = 0; i < o1.size(); i++) {
            Object jArray = o1.getJSONObject(i);
            if (jArray.getClass().toString().endsWith("JSONObject")) {
                o2.add(transObject((JSONObject) jArray));
            } else if (jArray.getClass().toString().endsWith("JSONArray")) {
                o2.add(transArray((JSONArray) jArray));
            }
        }
        return o2;
    }

    public static JSONArray getJsonArrayFromList(List list) {
        JSONArray jsonArray = new JSONArray();
        try {
            if (!CollectionUtils.isEmpty(list)) {
                for (int i = 0; i < list.size(); i++) {
                    Map map = (Map) list.get(i);
                    JSONObject json = transObject(JSONObject.fromObject(map));
                    log.debug("json: {}", json);
                    jsonArray.add(json);
                }
            }
        } catch (Exception e) {
            log.error("", e);
        }
        return jsonArray;
    }

    public static String getJsonFromList1(List list) {
        String returnJsonStr = "[]";
        try {
            if (!CollectionUtils.isEmpty(list)) {
                JSONArray jsonArray = new JSONArray();
                for (int i = 0; i < list.size(); i++) {
                    Map map = (Map) list.get(i);
                    JSONObject json = transObject(JSONObject.fromObject(map));
                    log.debug("json: {}", json);
                    jsonArray.add(json);
                }
                returnJsonStr = jsonArray.toString();
                returnJsonStr = returnJsonStr.replace(":null", ":\"\"");
                log.debug("returnJsonStr: {}", returnJsonStr);
            }
        } catch (Exception e) {
            log.error("", e);
        }
        return returnJsonStr;
    }

    public static String getJsonFromList(List list) {
        String returnJsonStr = null;
        try {
            if (!CollectionUtils.isEmpty(list)) {
                JSONArray jsonArray = new JSONArray();
                for (int i = 0; i < list.size(); i++) {
                    Map map = (Map) list.get(i);
                    JSONObject json = transObject(JSONObject.fromObject(map));
                    log.debug("json: {}", json);
                    jsonArray.add(json);
                }
                returnJsonStr = jsonArray.toString();
                returnJsonStr = returnJsonStr.replace(":null", ":\"\"");
                log.debug("returnJsonStr: {}", returnJsonStr);
            }
        } catch (Exception e) {
            log.error("", e);
        }
        return returnJsonStr;
    }

    public static String getMD5Str(String str) {
        return DigestUtils.md5Hex(str);
    }


    public static String getRequestBody(HttpServletRequest request, String encode) throws Exception {
        return IOUtils.toString(request.getInputStream(), encode);
    }

    public static String Transform(String XMLData) throws Exception {
        String FF = " <xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\"> " + " <xsl:output indent=\"yes\" method=\"xml\" encoding=\"utf-8\" omit-xml-declaration=\"yes\"/> " + " <xsl:template match=\"*\">     <xsl:element name=\"{local-name()}\">  <xsl:apply-templates select=\"@* | node()\"/>  </xsl:element>  </xsl:template>  " + " <xsl:template match=\"@*\">    <xsl:attribute name=\"{local-name()}\">  <xsl:value-of select=\".\"/>  </xsl:attribute> </xsl:template> " + " <xsl:template match=\"comment() | text() | processing-instruction()\">  <xsl:copy/>   </xsl:template>   <xsl:template match=\"@*\">   <xsl:copy/>  </xsl:template>  </xsl:stylesheet>  ";
        TransformerFactory tFac = TransformerFactory.newInstance();
        ByteArrayInputStream InXSL = new ByteArrayInputStream(FF.getBytes("UTF-8"));
        StreamSource xslSource = new StreamSource(InXSL);
        Transformer transObj = tFac.newTransformer(xslSource);
        InputStream InXML = new ByteArrayInputStream(XMLData.getBytes("UTF-8"));
        Source source = new StreamSource(InXML);
        Writer outWriter = new StringWriter();
        StreamResult result = new StreamResult(outWriter);
        transObj.transform(source, result);
        String mResultStr = outWriter.toString();
        outWriter.close();
        log.debug("mResultStr:" + mResultStr);
        return mResultStr;
    }

    public static FTPClient getFtp(String host, int port, String username, String password, String type) {
        FTPClient ftp = new FTPClient();
        try {
            ftp.connect(host, port);
            log.debug("ftp.connect");
            boolean loginresult = ftp.login(username, password);
            log.debug("loginresult:{}", loginresult);
            if ("enterLocalPassiveMode".equals(type)) {
                ftp.enterLocalPassiveMode();
            } else if ("enterRemotePassiveMode".equals(type)) {
                ftp.enterRemotePassiveMode();
            } else {
                ftp.enterLocalActiveMode();
            }
            ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
            return ftp;
        } catch (Exception e) {
            log.error("FTP获取失败");
            log.error("", e);
            return null;
        }
    }

    public static boolean ftpCreateDir(String host, int port, String username, String password, String dir, String dirname, String type) throws Exception {
        boolean result = false;
        FTPClient ftp = null;
        FileInputStream input = null;
        try {
            ftp = getFtp(host, port, username, password, type);
            if (dir != null && !dir.equals("") && dir.length() > 0) {
                boolean changeResult = ftp.changeWorkingDirectory(dir);
                log.debug("ftpUploadFile_changeResult:{}", changeResult);
            }
            result = ftp.makeDirectory(dirname);
        } catch (Exception e) {
            log.error("", e);
        } finally {
            if (ftp != null) {
                ftp.disconnect();
            }
            if (input != null) {
                input.close();
            }
        }
        return result;
    }

    public static boolean ftpDeleteFile(String host, int port, String username, String password, String fileUrl, String type) throws Exception {
        boolean result = false;
        FTPClient ftp = null;
        FileInputStream input = null;
        try {
            ftp = getFtp(host, port, username, password, type);
            result = ftp.deleteFile(fileUrl);
        } catch (Exception e) {
            log.error("", e);
        } finally {
            if (ftp != null) {
                ftp.disconnect();
            }
            if (input != null) {
                input.close();
            }
        }
        return result;
    }

    public static boolean ftpUploadFile(String host, int port, String username, String password, String filePath, String dir, int timeout, String type) throws Exception {
        boolean result = false;
        File file = new File(filePath);
        FTPClient ftp = null;
        try (FileInputStream input = new FileInputStream(file);) {
            ftp = getFtp(host, port, username, password, type);
            ftp.setConnectTimeout(timeout * 1000);
           /* if (dir != null && !dir.equals("") && dir.length() > 0) {
                boolean changeResult = ftp.changeWorkingDirectory(dir);
                log.debug("ftpUploadFile_changeResult:" + changeResult);
            }*/
            if (StringUtils.isNotEmpty(dir)) {
                boolean changeResult = ftp.changeWorkingDirectory(dir);
                if (!changeResult) {
                    ftp.changeWorkingDirectory("/");
                    String[] dir1 = dir.split("/");
                    // 分层创建目录
                    for (String di : dir1) {
                        log.debug("dir:{}", di);
                        ftp.makeDirectory(di);
                        ftp.changeWorkingDirectory(di);
                    }
                    changeResult = ftp.changeWorkingDirectory(dir);
                }
                log.debug("ftpUploadFile_changeResult : {}", changeResult);
            }
            result = ftp.storeFile(file.getName(), input);
        } catch (Exception e) {
            log.error("", e);
        } finally {
            if (ftp != null) {
                ftp.disconnect();
            }
        }
        return result;
    }

    public static boolean ftpDownLoadFile(String host, int port, String username, String password, String downLoadPath, String ftpUrl, int timeout, String type) throws Exception {
        boolean result = false;
        FTPClient ftp = null;
        File file = new File(downLoadPath);
        try (FileOutputStream fos = new FileOutputStream(file);) {
            ftp = getFtp(host, port, username, password, type);
            ftp.setConnectTimeout(timeout * 1000);
            ftp.setDataTimeout(timeout * 1000);
            ftp.setDefaultTimeout(timeout * 1000);
            ftp.setSoTimeout(timeout * 1000);
            result = ftp.retrieveFile(new String(ftpUrl.getBytes(), StandardCharsets.ISO_8859_1), fos);
        } catch (Exception e) {
            log.error("", e);
        } finally {
            if (ftp != null) {
                ftp.disconnect();
            }
        }
        return result;
    }

    public static boolean downloadFile(String remoteFileName, String localDires, String remoteDownLoadPath, FTPClient ftp) throws Exception {
        String strFilePath = localDires + remoteFileName;
        log.debug("strFilePath:{}", strFilePath);
        boolean success = false;
        try (BufferedOutputStream outStream = new BufferedOutputStream(new FileOutputStream(strFilePath))) {
            ftp.changeWorkingDirectory(remoteDownLoadPath);
            success = ftp.retrieveFile(new String(remoteFileName.getBytes(), StandardCharsets.ISO_8859_1), outStream);
        } catch (Exception e) {
            log.error("", e);
        }
        return success;
    }

    public static boolean downLoadDirectory1(FTPClient ftp, String localDirectoryPath, String remoteDirectory) throws Exception {
        try {
            log.debug("localDirectoryPath:{}", localDirectoryPath);
            new File(localDirectoryPath).mkdirs();
            FTPFile[] allFile = ftp.listFiles(remoteDirectory);
            for (int currentFile = 0; currentFile < allFile.length; currentFile++) {
                if (!allFile[currentFile].isDirectory()) {
                    downloadFile(new String(allFile[currentFile].getName().getBytes(), StandardCharsets.UTF_8), localDirectoryPath, remoteDirectory, ftp);
                    //                	 downloadFile(allFile[currentFile].getName(),localDirectoryPath, remoteDirectory,ftp);
                }
            }
            for (int currentFile = 0; currentFile < allFile.length; currentFile++) {
                if (allFile[currentFile].isDirectory()) {
                    String strremoteDirectoryPath = remoteDirectory + File.separator + new String(allFile[currentFile].getName().getBytes(), "utf-8");
                    //                	String strremoteDirectoryPath = remoteDirectory + File.separator+ allFile[currentFile].getName();
                    downLoadDirectory1(ftp, localDirectoryPath, strremoteDirectoryPath);
                }
            }
        } catch (IOException e) {
            log.error("", e);
            return false;
        }
        return true;
    }

    public static boolean downLoadFtpDirectory(String host, int port, String username, String password, String type, String localDirectoryPath, String remoteDirectory) throws Exception {
        FTPClient ftp = null;
        try {
            ftp = getFtp(host, port, username, password, type);
            ftp.setControlEncoding("utf-8");
            downLoadDirectory1(ftp, localDirectoryPath, remoteDirectory);
        } catch (IOException e) {
            log.error("", e);
            return false;
        } finally {
            if (ftp != null) {
                ftp.disconnect();
            }
        }
        return true;
    }

    public static boolean httpDownLoadFile(String httpUrl, String saveFile, int timeout) throws Exception {
        return httpDownLoadFileWithHead(httpUrl, saveFile, timeout, null);
    }

    public static boolean httpDownLoadFileWithHead(String httpUrl, String saveFile, int timeout, Map map) throws Exception {
        boolean result = false;
        URLConnection conn;
        try {
            int bytesum = 0;
            int byteread = 0;
            URL url = new URL(httpUrl);
            conn = url.openConnection();
            conn.setReadTimeout(timeout * 1000);
            if (map != null) {
                Iterator entries = map.entrySet().iterator();
                while (entries.hasNext()) {
                    Map.Entry entry = (Map.Entry) entries.next();
                    String key = (String) entry.getKey();
                    log.debug("key:{}", key);
                    String value = (String) entry.getValue();
                    log.debug("value:{}", value);
                    conn.setRequestProperty(key, value);
                }
            }
            try (InputStream inStream = conn.getInputStream(); FileOutputStream fs = new FileOutputStream(saveFile);) {
                byte[] buffer = new byte[1204];
                while ((byteread = inStream.read(buffer)) != -1) {
                    bytesum += byteread;
                    fs.write(buffer, 0, byteread);
                }
            } catch (Exception e1) {
                log.error("", e1);
                throw e1;
            }
            result = true;
        } catch (Exception e) {
            log.error("", e);
        }
        return result;
    }

    public static void appendFileContent(String fileName, String content) throws IOException {
        try (FileWriter writer = new FileWriter(fileName, true)) {
            //打开一个写文件器，构造函数中的第二个参数true表示以追加形式写文件
            writer.write(content);
        } catch (IOException e) {
            log.error("", e);
        }
    }

    public static boolean createDir(String destDirName) {
        File dir = new File(destDirName);
        if (dir.exists()) {
            log.error("创建目录 :{} 失败，目标目录已经存在", destDirName);
            return false;
        }
        if (!destDirName.endsWith(File.separator)) {
            destDirName = destDirName + File.separator;
        }
        //创建目录
        if (dir.mkdirs()) {
            log.debug("创建目录 :{} 成功！", destDirName);
            return true;
        } else {
            log.error("创建目录 :{} 失败！", destDirName);
            return false;
        }
    }

    public static void copyDir(String path, String copyPath) throws IOException {
        File filePath = new File(path);
        if (filePath.isDirectory()) {
            File[] list = filePath.listFiles();
            if (list != null && list.length > 0) {
                for (int i = 0; i < list.length; i++) {
                    String newPath = path + File.separator + list[i].getName();
                    String newCopyPath = copyPath + File.separator + list[i].getName();
                    copyDir(newPath, newCopyPath);
                }
            }
        } else if (filePath.isFile()) {
            try (DataInputStream read = new DataInputStream(new BufferedInputStream(new FileInputStream(path))); DataOutputStream write = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(copyPath)));) {
                byte[] buf = new byte[1024 * 512];
                while (read.read(buf) != -1) {
                    write.write(buf);
                }
            } catch (Exception e1) {
                log.error("", e1);
            }
        } else {
            log.error("请输入正确的文件名或路径名");
        }
    }

    public static String getSHA256Str(String str) {
        MessageDigest messageDigest;
        String encdeStr = "";
        try {
            messageDigest = MessageDigest.getInstance("SHA-256");
            byte[] hash = messageDigest.digest(str.getBytes(StandardCharsets.UTF_8));
            encdeStr = Hex.encodeHexString(hash);
        } catch (Exception e) {
            log.error("", e);
        }
        return encdeStr;
    }

    /*public static boolean doCMD(String command) throws Exception {
        boolean flag = false;
        Process process = null;
        try {
            log.debug("command:" + command);
            process = Runtime.getRuntime().exec(command);
            InputStream is = process.getInputStream();
            InputStream is2 = process.getErrorStream();
            byte[] isbt = readStream(is);
            byte[] is2bt = readStream(is2);
            int exitcode = process.waitFor();
            process.destroy();
            log.debug("exitcode:" + exitcode);
            if (exitcode == 0) {
                flag = true;
                log.debug("doCMD successfully");
            } else {
                log.error("doCMD failed and return " + exitcode);
            }
        } catch (Exception e) {
            log.error("", e);
        } finally {
            if (process != null) {
                process.getInputStream().close();
                process.getOutputStream().close();
                process.getErrorStream().close();
            }
        }
        return flag;
    }*/

    public static byte[] readStream(InputStream inStream) throws Exception {
        ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len = -1;
        while ((len = inStream.read(buffer)) != -1) {
            outSteam.write(buffer, 0, len);
        }
        outSteam.close();
        inStream.close();
        return outSteam.toByteArray();
    }

    public static boolean stringBytesToFile(String str, String filepath) throws Exception {
        File outfile = new File(filepath);
        Boolean result = false;
        try (DataOutputStream fw = new DataOutputStream(new FileOutputStream(outfile))) {
            fw.write(Base64.decodeBase64(str));
            result = true;
        } catch (Exception e) {
            log.error("", e);
        }
        return result;
    }

    public static String getFileBinaryStr(String filepath) throws Exception {

        String result = "";
        try (InputStream is = new FileInputStream(new File(filepath)); ByteArrayOutputStream bytestream = new ByteArrayOutputStream();) {
            byte[] bb = new byte[2048];
            int ch;
            ch = is.read(bb);
            while (ch != -1) {
                bytestream.write(bb, 0, ch);
                ch = is.read(bb);
            }
            byte[] by = bytestream.toByteArray();
            result = new String(Base64.encodeBase64(by));
        } catch (Exception e) {
            log.error("", e);
        }
        return result;
    }

    public static String getFileStr(String filepath, String encode) throws Exception {

        String result = "";
        try (InputStream is = new FileInputStream(new File(filepath)); ByteArrayOutputStream bytestream = new ByteArrayOutputStream();) {
            byte[] bb = new byte[2048];
            int ch;
            ch = is.read(bb);
            while (ch != -1) {
                bytestream.write(bb, 0, ch);
                ch = is.read(bb);
            }
            result = bytestream.toString(encode);
        } catch (Exception e) {
            log.error("", e);
        }
        return result;
    }

    public static String aesEncrypt(String content, String password) throws Exception {
        return AES.encrypt(content, password);
    }

    public static String aesDecrypt(String content, String password) throws Exception {
        return AES.decrypt(content, password);
    }

    public static String rsaEncrypt(String content, String privateKey) throws Exception {
        return RSAUtils.encryptByPrivateKey(content, privateKey);
    }

    public static String SHA256WithRSAEncrypt(String content, String privateKey) throws Exception {
        PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(Base64Utils.decodeFromString(privateKey));
        KeyFactory keyf = KeyFactory.getInstance("RSA");
        PrivateKey priKey = keyf.generatePrivate(priPKCS8);
        Signature signature = Signature.getInstance("SHA256WithRSA");
        signature.initSign(priKey);
        signature.update(content.getBytes(StandardCharsets.UTF_8));
        byte[] signed = signature.sign();
        return Base64Utils.encodeToString(signed);
    }

    public static String rsaDecrypt(String content, String publicKey) throws Exception {
        return RSAUtils.decryptByPublicKey(content, publicKey);
    }

    public static String getServiceUrl(HttpServletRequest request) {
        String urlPath = request.getRequestURL().toString();
        urlPath = urlPath.substring(0, urlPath.lastIndexOf("/"));
        return urlPath;
    }

    public static Session getjschSession(String host, String username, int port) throws JSchException {
        JSch jsch = new JSch();
        return jsch.getSession(username, host, port);
    }

    public static ChannelSftp sftpConnect(String password, Session sshSession, int timeout) {
        ChannelSftp sftp = null;
        try {
            sshSession.setPassword(password);
            Properties sshConfig = new Properties();
            sshConfig.put("StrictHostKeyChecking", "no");
            sshSession.setConfig(sshConfig);
            sshSession.setTimeout(timeout); // 设置timeout时间
            log.debug("sshSession.getPort():{}", sshSession.getPort());
            log.debug("sshSession.getHost():{}", sshSession.getHost());
            log.debug("sshSession.getUserName():{}", sshSession.getUserName());
            sshSession.connect();
            log.debug("sshSession connect success");
            Channel channel = sshSession.openChannel("sftp");
            channel.connect(timeout);
            log.debug("channel connect success");
            sftp = (ChannelSftp) channel;
        } catch (Exception e) {
            log.error("", e);
        }
        return sftp;
    }

    public static void disconnectSftp(ChannelSftp sftp, Session sshSession) {
        if (sftp != null && sftp.isConnected()) {
            sftp.disconnect();
        }
        if (sshSession.isConnected()) {
            sshSession.disconnect();
        }
    }

    /**
     * SFTP下载单个文件
     * //     * @param remotPath：远程下载文件路径
     *
     * @param localPath：本地文件路径
     * @return
     */
    public static boolean downloadFileSftp(String host, String username, String password, int port, String remotePath, String localPath, int timeout) {
        ChannelSftp sftp = null;
        Session sshSession = null;
        boolean downloadFileresult = false;
        File file = new File(localPath);
        try (FileOutputStream fieloutput = new FileOutputStream(file);) {
            sshSession = getjschSession(host, username, port);
            sftp = sftpConnect(password, sshSession, timeout);
            sftp.get(remotePath, fieloutput);
            downloadFileresult = true;
        } catch (Exception e) {
            log.error("", e);
        } finally {
            disconnectSftp(sftp, sshSession);
        }
        return downloadFileresult;

    }

    public static ArrayList lsFileList(String host, String username, String password, int port, String remotePath, int timeout) {
        ChannelSftp sftp = null;
        Session sshSession = null;
        ArrayList ar = new ArrayList();
        try {
            sshSession = getjschSession(host, username, port);
            sftp = sftpConnect(password, sshSession, timeout);
            Vector<LsEntry> vector = sftp.ls(remotePath);
            if (!CollectionUtils.isEmpty(vector)) {
                for (int i = 0; i < vector.size(); i++) {
                    LsEntry lsEntry = vector.get(i);
                    ar.add(lsEntry.getFilename());
                }
            }
        } catch (Exception e) {
            log.error("", e);
        } finally {
            disconnectSftp(sftp, sshSession);
        }
        return ar;
    }

    /**
     * 上传单个文件
     *
     * @param remotePath：远程保存目录
     * @param remoteFileName：保存文件名
     * @param localPath：本地文件路径
     * @return
     */
    public static boolean uploadFile(String host, String username, String password, int port, String remotePath, String remoteFileName, String localPath, int timeout) {
        ChannelSftp sftp = null;
        Session sshSession = null;
        boolean uploadFileresult = false;
        File file = new File(localPath);
        try (FileInputStream in = new FileInputStream(file);) {
            sshSession = getjschSession(host, username, port);
            sftp = sftpConnect(password, sshSession, timeout);
            if (remotePath != null && !remotePath.equals("") && remotePath.length() > 0) {
                if (!isDirExistSftp(remotePath, sftp)) {
                    sftp.mkdir(remotePath);
                }
                sftp.cd(remotePath);
            }
            sftp.put(in, remoteFileName);
            uploadFileresult = true;
        } catch (Exception e) {
            log.error("", e);
        } finally {
            disconnectSftp(sftp, sshSession);
        }
        return uploadFileresult;
    }

    public static boolean isDirExistSftp(String directory, ChannelSftp sftp) {
        try {
            log.debug("directory:{}", directory);
            SftpATTRS sftpATTRS = sftp.lstat(directory);
            return sftpATTRS.isDir();
        } catch (Exception e) {
            log.error("", e);
            return false;
        }
    }

    /**
     * 删除stfp文件
     *
     * @param directory：要删除文件路径
     */
    public static boolean deleteSFTP(String host, String username, String password, int port, String directory, int timeout) {
        ChannelSftp sftp = null;
        Session sshSession = null;
        boolean deleteSFTPresult = false;
        try {
            sshSession = getjschSession(host, username, port);
            sftp = sftpConnect(password, sshSession, timeout);
            sftp.rm(directory);
            deleteSFTPresult = true;
        } catch (Exception e) {
            log.error("", e);
        } finally {
            disconnectSftp(sftp, sshSession);
        }
        return deleteSFTPresult;
    }

    //    public static String[][] CSVParser(String filepath) throws Exception{
    //    	try (InputStream in=new FileInputStream(new File(filepath));){
    //    		ExcelCSVParser csvParser=new ExcelCSVParser(in);
    //    		String[][] currLine=csvParser.getAllValues();
    //    		return currLine;
    //    	}catch(Exception e){
    //    		log.error("",e);
    //    		throw e;
    //    	}
    //    }
    public static String calculate(String bizParams, String sysParams) {
        StringBuilder result = new StringBuilder();
        int bizLength = bizParams.length();
        int sysLength = sysParams.length();
        int length = bizLength > sysLength ? bizLength : sysLength;
        for (int i = 0; i < length; i++) {
            int r = 0;
            if ((i < bizLength) && (i < sysLength)) {
                r = bizParams.charAt(i) & sysParams.charAt(i);
            } else if (i < bizLength) {
                r = bizParams.charAt(i) & 0x6C;
            } else {
                r = sysParams.charAt(i) & 0x6C;
            }
            result.append(r);
        }
        return result.toString();
    }

    public static void sendMail(String host, int port, String sendAdderss, String username, String password, String receviceAddress, String subject, String content, String type, String emlFilePath, List attachmentList, boolean sendFlag) throws Exception {
        Properties properties = new Properties();
        properties.put("mail.transport.protocol", "smtp");// 连接协议
        properties.put("mail.smtp.host", host);// 主机名
        properties.put("mail.smtp.port", port);// 端口号
        properties.put("mail.smtp.auth", "true");
        // 得到回话对象
        javax.mail.Session session = javax.mail.Session.getInstance(properties);
        // 获取邮件对象
        MimeMessage message = new MimeMessage(session);
        // 设置发件人邮箱地址
        message.setFrom(new InternetAddress(sendAdderss));
        // 设置收件人邮箱地址
        message.setRecipients(javax.mail.Message.RecipientType.TO, new InternetAddress[]{new InternetAddress(receviceAddress)});
        //message.setRecipient(Message.RecipientType.TO, new InternetAddress("xxx@qq.com"));//一个收件人
        // 设置邮件标题
        message.setSubject(subject);


        MimeMultipart msgMultipart = new MimeMultipart("mixed");
        MimeBodyPart mbpContent = new MimeBodyPart();
        if ("html".equals(type)) {
            mbpContent.setContent(content, "text/html;charset=utf-8");
        } else {
            mbpContent.setText(content);
        }
        msgMultipart.addBodyPart(mbpContent);

        if (!CollectionUtils.isEmpty(attachmentList)) {
            for (int i = 0; i < attachmentList.size(); i++) {
                MimeBodyPart attachment = new MimeBodyPart();
                DataHandler dh = new DataHandler(new FileDataSource((String) attachmentList.get(i)));
                attachment.setDataHandler(dh);
                attachment.setFileName(MimeUtility.encodeText(dh.getName()));
                msgMultipart.addBodyPart(attachment);
            }
        }
        message.setContent(msgMultipart);
        File file = new File(emlFilePath);
        try (FileOutputStream fos = new FileOutputStream(file);) {
            message.writeTo(fos);
        } catch (Exception e) {
            log.error("", e);
            throw e;
        }

        if (!sendFlag) {
            // 得到邮差对象
            Transport transport = session.getTransport();
            // 连接自己的邮箱账户
            transport.connect(username, password);// 密码为QQ邮箱开通的stmp服务后得到的客户端授权码
            // 发送邮件
            transport.sendMessage(message, message.getAllRecipients());
            transport.close();
        }
    }

    public static String restfulService(String url, String requestMethod, Map headMap, String body, int timeout, String enCode) throws Exception {
        URL restURL = new URL(url);
        HttpURLConnection conn = (HttpURLConnection) restURL.openConnection();
        StringBuilder sb = new StringBuilder();
        try {
            conn.setConnectTimeout(timeout);
            conn.setRequestMethod(requestMethod); // POST GET PUT DELETE
            if (headMap != null) {
                Iterator entries = headMap.entrySet().iterator();
                while (entries.hasNext()) {
                    Map.Entry entry = (Map.Entry) entries.next();
                    String key = (String) entry.getKey();
                    log.debug("key:{}", key);
                    String value = (String) entry.getValue();
                    log.debug("value:{}", value);
                    conn.setRequestProperty(key, value);
                }
            }
            if (body != null && body.length() > 0) {
                conn.setDoOutput(true);
                try (OutputStream out1 = conn.getOutputStream(); OutputStreamWriter out = new OutputStreamWriter(out1, enCode);) {
                    out.write(body);
                } catch (Exception e2) {
                    log.error("", e2);
                }
            }
            try (InputStream in = conn.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(in, enCode));) {
                String line;
                while ((line = br.readLine()) != null) {
                    sb.append(line + "\n");
                }
            } catch (Exception e1) {
                log.error("", e1);
            }

        } catch (Exception e) {
            log.error("", e);
        } finally {
            if (conn != null) {
                conn.disconnect();
            }
        }
        return sb.toString();

    }

    public static String doSocketShortConn(String host, int port, int timeout, String bodyStr, int readLen, String enCode1, String enCode2, String enCode3) throws Exception {
        String returnStr = "";
        try (Socket socket = new Socket(host, port)) {
            socket.setSoTimeout(timeout);
            try (InputStream input = socket.getInputStream(); InputStreamReader isr = new InputStreamReader(input, enCode1); OutputStream output = socket.getOutputStream(); InputStream in = new BufferedInputStream(socket.getInputStream()); ByteArrayOutputStream buf = new ByteArrayOutputStream();) {
                output.write(bodyStr.getBytes(enCode2));
                output.flush();
                int count = 0;
                byte[] readBuf = new byte[readLen];
                count = in.read(readBuf);
                if (count > 10000) {
                    throw new Exception("input too long");
                }
                buf.write(readBuf, 0, count);
                returnStr = new String(new String(buf.toByteArray(), enCode3));
            } catch (Exception e) {
                log.error("", e);
                throw e;
            }
            log.debug("returnStr123:{}", returnStr);
        } catch (Exception e) {
            log.error("", e);
            throw e;
        }
        return returnStr;

    }

    public static Map jwtsParseToken(String token, String jwkEndpoint) throws Exception {
        ConfigurableJWTProcessor jwtProcessor = new DefaultJWTProcessor();
        JWKSource keySource = new RemoteJWKSet(new URL(jwkEndpoint));
        JWSAlgorithm expectedJWSAlg = JWSAlgorithm.RS256;
        JWSKeySelector keySelector = new JWSVerificationKeySelector(expectedJWSAlg, keySource);
        jwtProcessor.setJWSKeySelector(keySelector);
        JWTClaimsSet claimsSet = jwtProcessor.process(token, null);
        return claimsSet.getClaims();
    }

    public static String postFileMultiPart(String url, int timeout, String paramName, String filePath) throws Exception {
        CloseableHttpClient httpclient = null;
        CloseableHttpResponse response = null;
        String result = "";
        try {
            HttpPost post = new HttpPost(url);
            post.setHeader("Content-examine", "multipart/form-data; charset=utf-8");
            RequestConfig defaultRequestConfig = RequestConfig.custom().setConnectTimeout(timeout).setConnectionRequestTimeout(timeout).setSocketTimeout(timeout).build();
            post.setConfig(defaultRequestConfig);
            MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
            multipartEntityBuilder.addBinaryBody(paramName, new File(filePath));
            HttpEntity reqEntity = multipartEntityBuilder.build();
            post.setEntity(reqEntity);
            response = httpclient.execute(post);
            HttpEntity entity = response.getEntity();
            result = EntityUtils.toString(entity, StandardCharsets.UTF_8);
        } catch (Exception e) {
            log.error("", e);
        } finally {
            if (response != null) {
                response.close();
            }
            if (httpclient != null) {
                httpclient.close();
            }
        }
        return result;
    }

    /*
     * 解析csv文件
     * */
    //    public static String[][] csvParser(String filepath) throws Exception {
    //        Charset detect = FileUtils.detect(new File(filepath));
    //        log.debug("当前文件编码为: {}", detect);
    //        try (InputStream in = new FileInputStream(new File(filepath))) {
    //            ExcelCSVParser csvParser = new ExcelCSVParser(new InputStreamReader(in, detect.toString()));
    //            return csvParser.getAllValues();
    //        } catch (Exception e) {
    //            log.error("", e);
    //            throw e;
    //        }
    //    }

    public static Object[][] excelParser(String filePath) throws Exception {
        List<Object[]> v = new ArrayList<>();
        InputStream inputStream = new BufferedInputStream(FileUtils.openInputStream(filePath));
        ZipSecureFile.setMinInflateRatio(-1.0d);
        EzCellFactory.read(inputStream, data -> {
            v.add(data.toArray());
        });
        Object[][] result = new Object[v.size()][];
        return v.toArray(result);
    }

    public static List<String> excelParser1(String filePath) throws Exception {
        List<String> list = new ArrayList<>();
        InputStream inputStream = new BufferedInputStream(FileUtils.openInputStream(filePath));
        ZipSecureFile.setMinInflateRatio(-1.0d);
        EzCellFactory.read(inputStream, data -> {
            list.add(data.toString());
        });
        log.debug("list size: {}", list.size());
        return list;
    }


    //导出数据库查询对象
    public static boolean csvExport(String sql, String filePath) throws Exception {
        boolean result = true;
        try (BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File(filePath)), StandardCharsets.UTF_8));) {
            StringBuilder buf = new StringBuilder();
            EliteBean eliteBean = SpringContextUtil.getBean(EliteBean.class);
            SqlRowSet sqlRowSet = eliteBean.chaxun_sqlRowSet(sql, "dataSource");
            int colcnt = sqlRowSet.getMetaData().getColumnCount();
            log.debug("表头数目为:{}", colcnt);
            //读取表头内容
            for (int i = 1; i <= colcnt; i++) {
                String title = sqlRowSet.getMetaData().getColumnLabel(i);
                buf.append(title).append(CSV_COLUMN_SEPARATOR);
            }
            buf.append(CSV_ROW_SEPARATOR);
            //读取表数据内容
            sqlRowSet.beforeFirst();
            while (sqlRowSet.next()) {
                for (int i = 1; i <= colcnt; i++) {
                    String colv = sqlRowSet.getString(i);
                    buf.append(colv).append(CSV_COLUMN_SEPARATOR);
                }
                buf.append(CSV_ROW_SEPARATOR);
            }
            //写入CSV文件
            bw.write(buf.toString());
            bw.flush();
        } catch (IOException e) {
            result = false;
            log.error("", e);
        }
        return result;
    }

    //导出普通list
    public static boolean csvExport1(String fileName, List list, Object[] title) throws IOException {
        boolean result = true;
        CSVPrinter printer = null;
        Object[] objects = null;
        List<List<Object>> resultList = new ArrayList<>();
        log.debug("list size: {}", list.size());
        if (!CollectionUtils.isEmpty(list)) {
            if (list.get(0) instanceof List) {
                for (Object li : list) {
                    resultList.add((List<Object>) li);
                }
            } else {
                resultList.add(list);
            }
        }
        try (FileWriter writer = new FileWriter(fileName)) {
            printer = CSVFormat.EXCEL.print(writer);
            //判断是否需要加上表头
            if (title != null) {
                printer.printRecord(title);
            }
            for (List<Object> objectList : resultList) {
                objects = objectList.toArray();
                printer.printRecord(objects);
                log.debug("{}", Arrays.toString(objects));
            }
        } catch (IOException e) {
            result = false;
            log.error("", e);
        } finally {
            printer.close();
        }
        return result;
    }

    public static boolean convertAudio(String filePath, String savePath) {
        boolean result = false;
        try (FileInputStream inputStream = new FileInputStream(new File(filePath)); FileOutputStream fos = new FileOutputStream(new File(savePath)); java.io.ByteArrayOutputStream wavBos = new java.io.ByteArrayOutputStream(); java.io.ByteArrayOutputStream bos = new java.io.ByteArrayOutputStream()) {

            byte[] audioData = new byte[1024 * 1024];
            int byteread = 0;
            while ((byteread = inputStream.read(audioData)) != -1) {
                bos.write(audioData, 0, byteread);
            }
            byte[] wavData = bos.toByteArray();
            byte[] wavHeader = new WaveHeader(8000, (short) 16, wavData.length).getHeader();
            wavBos.write(wavHeader);
            wavBos.write(wavData);
            fos.write(wavBos.toByteArray());
            result = true;
        } catch (IOException e) {
            log.error("", e);
        }
        return result;
    }

    public static List<String> regex(String input, String regex) {
        Pattern p = Pattern.compile(regex);
        Matcher m = p.matcher(input);
        List<String> targets = new ArrayList<>();
        while (m.find()) {
            targets.add(m.group(0));
            targets.add(m.group(1));
        }
        return targets;
    }

    public static boolean isValid(String idCard) {
        idCard = idCard.trim();
        if (StringUtils.isEmpty(idCard)) {
            return false;
        }
        String regex1 = "(^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$)|" + "(^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}$)";
        Pattern pat = Pattern.compile(regex1);
        Matcher mat = pat.matcher(idCard);
        if (mat.matches()) {
            if (idCard.length() == 18) {
                try {
                    char[] charArray = idCard.toCharArray();
                    // 前十七位加权因子
                    int[] idCardWi = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
                    // 这是除以11后，可能产生的11位余数对应的验证码
                    String[] idCardY = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"};
                    int sum = 0;
                    for (int i = 0; i < idCardWi.length; i++) {
                        int current = Integer.parseInt(String.valueOf(charArray[i]));
                        int count = current * idCardWi[i];
                        sum += count;
                    }
                    char idCardLast = charArray[17];
                    int idCardMod = sum % 11;
                    return idCardY[idCardMod].equalsIgnoreCase(String.valueOf(idCardLast));
                } catch (Exception e) {
                    log.error("", e);
                    return false;
                }
            }
            if (idCard.length() == 15) {
                isValid(String.valueOf(idCardMethod15To18(idCard)));
            }
        }
        return false;
    }

    /**
     * 15 位身份证号码转 18 位
     * <p>
     * 15位身份证号码：第7、8位为出生年份（两位数），第9、10位为出生月份，第11、12位代表出生日期，第15位代表性别，奇数为男，偶数为女。
     * 18位身份证号码：第7、8、9、10位为出生年份（四位数），第11、第12位为出生月份，第13、14位代表出生日期，第17位代表性别，奇数为男，偶数为女。
     */
    public static StringBuffer idCardMethod15To18(String idCard) {
        //将字符串转化为buffer进行操作
        StringBuffer stringBuffer = new StringBuffer(idCard);
        //身份证最后一位校验码，X代表10（顺序固定）
        char[] checkIndex = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'};
        int sum = 0;
        //在第6位插入年份的前两位19
        stringBuffer.insert(6, "19");
        for (int i = 0; i < stringBuffer.length(); i++) {
            char c = stringBuffer.charAt(i);
            //前17位数字
            int ai = Character.getNumericValue(c);
            //前17位每位对应的系数（7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2 ）
            int wi = ((int) Math.pow(2, stringBuffer.length() - i)) % 11;
            //总和（每位数字乘以系数再相加）
            sum = sum + ai * wi;
        }
        //总和除以11求余
        int indexOf = sum % 11;
        //根据余数作为下表在校验码数组里取值
        stringBuffer.append(checkIndex[indexOf]);
        return stringBuffer;
    }

    /**
     * 获取出生日期
     */
    public static String getBirthday(String idCard) {
        if (!isValid(idCard)) {
            return null;
        }
        String year = "";
        String month = "";
        String day = "";
        if (idCard.length() == 18) {
            year = idCard.substring(6).substring(0, 4);
            month = idCard.substring(10).substring(0, 2);
            day = idCard.substring(12).substring(0, 2);
        } else if (idCard.length() == 15) {
            year = "19" + idCard.substring(6, 8);
            month = idCard.substring(8, 10);
            day = idCard.substring(10, 12);
        }
        return year + "-" + month + "-" + day;
    }

    /**
     * 获取性别
     * 0=女性,1=男性
     */
    public static int getGender(String idCard) {
        if (!isValid(idCard)) {
            return -1;
        }
        int number = 0;
        if (idCard.length() == 18) {
            number = Character.getNumericValue(idCard.charAt(idCard.length() - 2));
        } else if (idCard.length() == 15) {
            number = Character.getNumericValue(idCard.charAt(idCard.length() - 1));
        }
        return number % 2;
    }

    /**
     * 过滤XSS特殊字符
     *
     * @param s
     * @return
     */
    public static String xssEncode(String s) {
        // XSS静态过滤方法
        if (s == null || s.isEmpty()) {
            return s;
        }
        StringBuilder sb = new StringBuilder(s.length() + 16);
        Pattern scriptPattern = Pattern.compile("<script>(.*?)</script>", Pattern.CASE_INSENSITIVE);
        s = scriptPattern.matcher(s).replaceAll("");
        scriptPattern = Pattern.compile("eval\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
        s = scriptPattern.matcher(s).replaceAll(" ");
        scriptPattern = Pattern.compile("expression\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
        s = scriptPattern.matcher(s).replaceAll(" ");
        scriptPattern = Pattern.compile("onload(.*?)=", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
        s = scriptPattern.matcher(s).replaceAll(" ");
        scriptPattern = Pattern.compile("onerror(.*?)=", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
        s = scriptPattern.matcher(s).replaceAll(" ");
        scriptPattern = Pattern.compile("alert(.*?)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
        s = scriptPattern.matcher(s).replaceAll(" ");
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            switch (c) {
                case '>':
                    sb.append('＞');// 全角大于号
                    break;
                case '<':
                    sb.append('＜');// 全角小于号
                    break;
                case '\'':
                    sb.append('‘');// 全角单引号
                    break;
                case '\"':
                    sb.append('“');// 全角双引号
                    break;
                case '&':
                    sb.append('＆');// 全角
                    break;
                case '\\':
                    sb.append('＼');// 全角斜线
                    break;
                case '#':
                    sb.append('＃');// 全角井号
                    break;
                case '(':
                    sb.append('（');//
                    break;
                case ')':
                    sb.append('）');//
                    break;
                default:
                    sb.append(c);
                    break;
            }
        }
        return sb.toString();
    }

    /**
     * get请求带body,不推荐使用
     */
    public static String doHttpGetUseBody(String url, String param, Map<String, String> header, String encoding) throws Exception {
        if (StringUtils.isEmpty(encoding)) {
            encoding = "UTF-8";
        }
        CloseableHttpClient client = null;
        CloseableHttpResponse response = null;
        String body = "";
        try {
            SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, new TrustAllStrategy()).build();
            client = HttpClients.custom().setSSLContext(sslContext).setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE).build();
            BaseHttpMethod.HttpGetWithEntity httpGetWithEntity = new BaseHttpMethod.HttpGetWithEntity(url);
            HttpEntity httpEntity = new StringEntity(param, ContentType.APPLICATION_JSON);
            httpGetWithEntity.setEntity(httpEntity);
            if (header != null && !header.isEmpty()) {
                for (Map.Entry<String, String> entry : header.entrySet()) {
                    httpGetWithEntity.setHeader(entry.getKey(), entry.getValue());
                }
            }
            response = client.execute(httpGetWithEntity);
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                body = EntityUtils.toString(entity, encoding);
            }
        } catch (Exception e) {
            log.error("", e);
        } finally {
            if (response != null) {
                response.close();
            }
            if (client != null) {
                client.close();
            }
        }
        return body;
    }

    public static boolean convertToImage(String inputPath, String outputPath) {
        HtmlParserImpl htmlParser = new HtmlParserImpl();
        try {
            File file = new File(inputPath);
            if (!file.exists()) {
                log.error("文件[{}]不存在", file);
                return false;
            }
            htmlParser.loadHtml(Jsoup.parse(file).html());
            ImageRenderer imageRenderer = new ImageRendererImpl(htmlParser);
            BufferedImage img = imageRenderer.getBufferedImage();
            ImageIO.write(img, "png", new File(outputPath));
        } catch (IOException e) {
            log.error("", e);
            return false;
        }
        return true;
    }

    public static void postProcessLog(String heads, String operateUrl, String method, String traceId, String remoteIp, String remoteServiceName, String result, int resultLength, long cos, int statusCode, String errorMsg, String requestParam, String payload) {
        CommonConfiguration commonConfiguration = SpringContextUtil.getBean("commonConfiguration");
        if (commonConfiguration.isUsePostProcessLog()) {
            PostProcessLogService processLogService = SpringContextUtil.getBean(PostProcessLogService.class);
            processLogService.postProcessLog(heads, operateUrl, method, traceId, remoteIp, remoteServiceName, result, resultLength, cos, statusCode, errorMsg, requestParam, payload);
        }
    }

    private Util() {
        throw new IllegalStateException("Util class");
    }
}
